/*本关任务：实现队列基本操作，并使用队列基本操作解决密码加密和解密问题。

密码加密原理描述如下：
将明文（一个字符串）的每个字符按照字母表后移，每个字符的后移个数由秘钥值列表确定，如果明文比密钥值列表长，可以从头再使用这个密钥值列表。
如明文：student，秘钥：2345，
则加密方法是：s（向后移动2位）变成u，t（向后移动3位）变成w，u （向后移动4位）变成y，d（向后移动5位） 变成i，此时秘钥用完，所以从头开始用2进行
移位加密，依此类推可以得到加密后的密文。而解密时，只需将密文根据秘钥反推就可以得到明文。
*/
/*
student 123
tvxegqu*/
#include <cstddef>
#include <iostream>
#include <malloc.h>
using namespace std;
#include <stdio.h>    
#include <stdlib.h>
#include <string.h>

typedef char DataType;

//队列数据元素结构
typedef struct node
{
	DataType info;
	struct node *next;
}QueueData;

typedef struct queueRecord {
	QueueData  *front, *rear;
}LINKQUEUE;

typedef struct queueRecord *PLinkQueue;

PLinkQueue createEmptyQueue_link()
{
	//创建一个空队列，实质：生成一个LINKQUEUE类型的结点，并给front 和 rear 成员赋值
	 //请在此处填写代码，完成相应功能
	 /*-------begin----------*/
    PLinkQueue l=(PLinkQueue)malloc(sizeof(struct node));
    l->front=(QueueData*)malloc(sizeof(struct node));
    l->rear=(QueueData*)malloc(sizeof(struct node));
    l->rear=l->front=NULL;
    return l;

	 /*-------end----------*/

}

int isEmptyQueue_link(PLinkQueue  queue)
{ //判定队列是否为空，实质： 看队列的front指针是否为空，若为空，则队列为空

  //请在此处填写代码，完成相应功能
	/*-------begin----------*/
    return queue->front==NULL;
	//如果为空，则返回1，如果不为空，返回0


	/*-------end----------*/
}

void enQueue_link(DataType x, PLinkQueue queue)
{
	//将数据元素x插入队尾。实质：生成一个struct node类型的结点，并给相应成员赋值后插入队尾
	 //请在此处填写代码，完成相应功能
	 /*-------begin----------*/
    QueueData* l=(QueueData*)malloc(sizeof(QueueData));
    l->next= NULL;
    l->info=x;
    if (queue->rear==NULL)
        {queue->rear=l;
        queue->front=l;
        }
    else{
    queue->rear->next=l;
    queue->rear=queue->rear->next;
    }
	 /*-------end----------*/
}
void enQueue_link(QueueData *p, PLinkQueue Q)
{
	//本函数的功能是将 struct node 类型的结点插入队尾，与enQueue_link(DataType x, PLinkQueue queue)的区别是，不需要生成结点

	   //请在此处填写代码，完成相应功能
	  /*-------begin----------*/
    Q->rear->next=p;
    if (Q->rear==NULL)
    {Q->rear=p;
        Q->front=p;
    }
    Q->rear=Q->rear->next;
	  /*-------end----------*/

}

DataType deQueue_link(PLinkQueue Q)
{
	//出队，实质： 取出Q队列的队首结点，返回该结点的数据元素，并将该结点使用enQueue_link(QueueData *p,PLinkQueue Q)插入队尾
	//本函数为针对本实验特殊设计，可实现秘钥的循环使用
	//请在此处填写代码，完成相应功能
   /*-------begin----------*/
    QueueData *p;
    p=Q->front;
    Q->front=Q->front->next;
    enQueue_link(p,Q);
    return p->info;


   /*-------end----------*/

}
/*  参数： src 放的是源文 ； key 放的是秘钥 ； dest 放加密后的密文
加密函数： 步骤提示
1. 初始化一个空队列Q
2. 将key数组的元素逐个插入队列Q
3. 逐个访问src数组的源文，并加密， 使用deQueue_link(Q)函数可得到队首秘钥，并使秘钥循环使用
*/
void decrypt(char src[], char key[], char dest[])
{
    int ter,j=0,ex;//存值
    PLinkQueue Q=createEmptyQueue_link();
    for (int i = 0; key[i]!='\0'; ++i)
        enQueue_link(key[i],Q);
    for (int i = 0;src[i]!='\0'; ++i)
    {
        ter=src[i]+(deQueue_link(Q)-'0');
        if (ter>122)
        {
            ex=ter-120;
            ter=ex+97;
            dest[j++]=ter;
        }
        else
            dest[j++]=ter;
    }
    dest[j]='\0';
}

int main(void)
{
	char src[80], key[20], dest[80];

	cin >> src;

	cin >> key;
	decrypt(src, key, dest);
	cout << dest;
}


